package BandB.Tool.GPhoneManager.AppManager.AppResore;

import java.io.File;
import java.util.LinkedList;
import java.util.List;

import BandB.Tool.GPhoneManager.ConfigManager;
import BandB.Tool.GPhoneManager.MediaListener;
import BandB.Tool.GPhoneManager.R;
import BandB.Tool.GPhoneManager.AppManager.Settings;
import android.app.Dialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

public final class AppRestoreManager extends ListActivity implements
		OnItemClickListener {

	protected static final String TAG = AppRestoreManager.class.getSimpleName();

	private static final byte MODE_LOADING = 0;
	private static final byte MODE_SHOW_LIST = 1;
	private static final byte MODE_SHOW_NO_ITEM = 2;

	private static final int MSG_START_LOADING = -1;
	private static final int MSG_SHOW_LOADING = 0;
	private static final int MSG_SHOW_LIST = 1;
	private static final int MSG_SHOW_NO_ITEMS = 2;
	protected static final int MSG_DELETE_FILES_COMPLETED = 3;
	protected static final int MSG_ADAPTER_DATA_CHANGED = 4;
	protected static final int MSG_SHOW_REMOVE_FOOT = 5;
	private static final byte[] SYNC = new byte[0];

	private byte mCurrentMode;

	private ListView mListViewBackup;
	private BackupListAdapter mBackupListAdapter;
	// private LinkedList<BackupItem> mBackupList;
	private TextView mNoBackupTextView;
	private TextView mLoadingView;
	private Button mBtnMore;
	private View mView;
	private View mLineView;
	private ProgressDialog mProgressDeleteDialog;
	private static final int DELETE_DIALOG = 1;
	private LinkedList<BackupItem> mQuequeFile;

	private PackageManager mPackageManager;
	private LayoutInflater mLayoutInflater;
	private ConfigManager mConfigManager;

	private final OnClickListener moreClickListener = new OnClickListener() {
		public void onClick(final View arg0) {
			Log.i(TAG, "more clicked");
			setMode(MODE_LOADING);
			startLoadingAllApks();
		};
	};

	private final FileFoundListener mFileListener = new FileFoundListener() {
		@Override
		public void onFileFound(final File file) {
			// TODO Auto-generated method stub
			if (mCurrentMode == MODE_LOADING) {
				mHandler.sendEmptyMessage(MSG_SHOW_LIST);
			}
			final PackageInfo info = mPackageManager.getPackageArchiveInfo(file
					.getAbsolutePath(), 0);
			final BackupItem item = new BackupItem();
			item.setBackupFile(file);
			item.setPackageInfo(info);
			item.setChecked(false);
			// mBackupListAdapter.addFileInfo(item);
			Log.i(TAG, "file found:" + file);
			synchronized (SYNC) {
				mQuequeFile.offer(item);
				mHandler.sendEmptyMessage(MSG_ADAPTER_DATA_CHANGED);
				try {
					SYNC.wait();
				} catch (final InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}

		@Override
		public void onAllFileFound() {
			// TODO Auto-generated method stub
			Log.i(TAG, "all file found.");
		}

		@Override
		public void onNoFileFound() {
			// TODO Auto-generated method stub
			mHandler.sendEmptyMessage(MSG_SHOW_NO_ITEMS);
		}
	};

	private final Handler mHandler = new Handler() {
		@Override
		public void handleMessage(final Message msg) {
			// TODO Auto-generated method stub
			switch (msg.what) {
			case MSG_SHOW_LOADING:
				setMode(MODE_LOADING);
				break;
			case MSG_SHOW_LIST:
				setMode(MODE_SHOW_LIST);
				break;
			case MSG_SHOW_REMOVE_FOOT:
				// setMode(MODE_SHOW_LIST);
				mListViewBackup.removeFooterView(mView);
				break;
			case MSG_SHOW_NO_ITEMS:
				setMode(MODE_SHOW_NO_ITEM);
				break;
			case MSG_DELETE_FILES_COMPLETED:
				if (null != mProgressDeleteDialog) {
					mProgressDeleteDialog.dismiss();
				}
				Toast.makeText(AppRestoreManager.this,
						"Succeed to delete files.", Toast.LENGTH_SHORT).show();
				mBackupListAdapter.notifyDataSetChanged();
				if (mBackupListAdapter.getCount() == 0) {
					setMode(MODE_SHOW_NO_ITEM);
				}
				break;
			case MSG_START_LOADING:
				startLoadingDefaultApks();
				break;
			case MSG_ADAPTER_DATA_CHANGED:
				// listViewBackup.setAdapter(mBackupListAdapter);
				synchronized (SYNC) {
					final BackupItem item = mQuequeFile.poll();
					mBackupListAdapter.addFileInfo(item);
					mBackupListAdapter.notifyDataSetChanged();
					SYNC.notify();
				}

				break;
			default:
				break;
			}
			super.handleMessage(msg);
		}
	};

	@Override
	protected void onCreate(final Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.backup_list);
		setTitle("App Restore");

		initializeElements();
		setMode(MODE_LOADING);
		mHandler.sendEmptyMessage(MSG_START_LOADING);
	}

	@Override
	protected Dialog onCreateDialog(final int id) {
		if (DELETE_DIALOG == id) {
			mProgressDeleteDialog = new ProgressDialog(this);
			mProgressDeleteDialog.setTitle("Delete");
			mProgressDeleteDialog.setMessage("Delete is processing...");
			mProgressDeleteDialog.setCancelable(true);
			mProgressDeleteDialog.setIndeterminate(true);
			return mProgressDeleteDialog;
		}
		return super.onCreateDialog(id);
	}

	@Override
	public void onItemClick(final AdapterView<?> parent, final View view,
			final int position, final long id) {
		mBackupListAdapter.setCheckedAt(position);
	}

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {
		final MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.backup_menu, menu);
		return super.onCreateOptionsMenu(menu);
	}

	@Override
	public boolean onOptionsItemSelected(final MenuItem item) {
		if (null == mBackupListAdapter || 0 == mBackupListAdapter.getCount()) {
			Toast.makeText(AppRestoreManager.this, "No backup item",
					Toast.LENGTH_SHORT).show();
			return super.onOptionsItemSelected(item);
		}
		switch (item.getItemId()) {
		case R.id.menu_select_all:
			mBackupListAdapter.checkAll();
			break;
		case R.id.menu_select_none:
			mBackupListAdapter.checkNothing();
			break;
		case R.id.menu_recover:
			List<BackupItem> checkList = mBackupListAdapter.getCheckedItem();
			if (checkList.size() == 0) {
				Toast.makeText(this, "You must select at least one file!",
						Toast.LENGTH_LONG).show();
			} else {
				installApp(checkList);
			}
			break;
		case R.id.menu_delete:
			final List<BackupItem> deleteCheList = mBackupListAdapter
					.getCheckedItem();
			if (deleteCheList.size() == 0) {
				Toast.makeText(this, "You must select one file at least!",
						Toast.LENGTH_LONG).show();
				break;
			}
			showDialog(DELETE_DIALOG);
			new Thread(new Runnable() {

				@Override
				public void run() {
					mBackupListAdapter.deleteFile(deleteCheList);
					mHandler.sendEmptyMessage(MSG_DELETE_FILES_COMPLETED);
				};
			}).start();
			break;
		default:
			break;
		}

		return super.onOptionsItemSelected(item);
	}

	private void initializeElements() {
		mQuequeFile = new LinkedList<BackupItem>();
		mNoBackupTextView = (TextView) findViewById(R.id.no_backup);
		mListViewBackup = getListView();
		mListViewBackup.setOnItemClickListener(this);
		mConfigManager = ConfigManager.getInstance(this);

		mLayoutInflater = LayoutInflater.from(AppRestoreManager.this);
		mView = mLayoutInflater.inflate(R.layout.backup_more, null);
		mLineView = mLayoutInflater.inflate(R.layout.backup_more_line, null);
		mListViewBackup.addFooterView(mView);
		mListViewBackup.addFooterView(mLineView);

		mBtnMore = (Button) findViewById(R.id.btnBacklistMore);
		mBtnMore.setOnClickListener(moreClickListener);
		mBackupListAdapter = new BackupListAdapter(this);
		mListViewBackup.setAdapter(mBackupListAdapter);
		mPackageManager = getPackageManager();
		mLoadingView = (TextView) findViewById(R.id.txtViewBackupLoading);

	}

	private void setMode(byte mode) {
		mCurrentMode = mode;
		switch (mode) {
		case MODE_LOADING:
			mLoadingView.setVisibility(View.VISIBLE);
			mListViewBackup.setVisibility(View.GONE);
			mNoBackupTextView.setVisibility(View.GONE);
			break;
		case MODE_SHOW_LIST:
			mLoadingView.setVisibility(View.GONE);
			mListViewBackup.setVisibility(View.VISIBLE);
			mNoBackupTextView.setVisibility(View.GONE);
			break;
		case MODE_SHOW_NO_ITEM:
			mLoadingView.setVisibility(View.GONE);
			mListViewBackup.setVisibility(View.GONE);
			mNoBackupTextView.setVisibility(View.VISIBLE);
			break;

		default:
			break;
		}
	}

	private void startLoadingDefaultApks() {
		if (!MediaListener.isSDCardAvailable()) {
			Toast.makeText(this, "SD Card doesn't exist, please check it.",
					Toast.LENGTH_SHORT).show();
			mHandler.sendEmptyMessage(MSG_SHOW_NO_ITEMS);
			return;
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				FileManager.setFileFoundListener(mFileListener);
				LinkedList<File> fileList = FileManager
						.getAllAppFile(Settings.APK_BACKUP_ROOT
								+ mConfigManager.getDefinedPath());
				if (0 != fileList.size()) {
					// mFileListener.onAllFileFound();
					mHandler.sendEmptyMessage(MSG_SHOW_LIST);
				} else {
					// mFileListener.onNoFileFound();
					mHandler.sendEmptyMessage(MSG_SHOW_NO_ITEMS);
				}
			}
		}).start();
	}

	private void startLoadingAllApks() {
		if (!MediaListener.isSDCardAvailable()) {
			Toast.makeText(this, "SD Card doesn't exist, please check it.",
					Toast.LENGTH_SHORT).show();
			mHandler.sendEmptyMessage(MSG_SHOW_NO_ITEMS);
			return;
		}
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				// FileManager.setFileFoundListener(mFileListener);
				mHandler.sendEmptyMessage(MSG_SHOW_REMOVE_FOOT);
				mBackupListAdapter.deleteAllFiles();
				LinkedList<File> fileList = FileManager
						.getAllAppFile(Settings.APK_BACKUP_ROOT);
				if (0 != fileList.size()) {
					// mFileListener.onAllFileFound();
					mHandler.sendEmptyMessage(MSG_SHOW_LIST);
				} else {
					// mFileListener.onNoFileFound();
					mHandler.sendEmptyMessage(MSG_SHOW_NO_ITEMS);
				}
			}
		}).start();
	}

	public void installApp(List<BackupItem> backupList) {
		int size = backupList.size();
		for (int i = 0; i < size; i++) {
			Uri installUri = Uri.fromFile(backupList.get(i).getBackupFile());
			Intent installIntent = new Intent(Intent.ACTION_VIEW);
			installIntent.setDataAndType(installUri,
					"application/vnd.android.package-archive");
			startActivity(installIntent);
		}

	}
}
